package org.handsomezhi.twocoupon.admin.config.redis;


import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSONObject;
import lombok.RequiredArgsConstructor;
import org.handsomezhi.twocoupon.admin.dao.entity.CouponTaskDO;
import org.handsomezhi.twocoupon.admin.dao.mapper.CouponTaskMapper;
import org.handsomezhi.twocoupon.admin.service.handler.excel.RowCountListener;
import org.redisson.api.RBlockingDeque;
import org.redisson.api.RedissonClient;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;


import java.util.concurrent.Executors;

/**
 * 优惠券延迟刷新发送条数兜底消费者｜这是兜底策略，一般来说不会执行这段逻辑
 * 如果延迟消息没有持久化成功，或者 Redis 挂了怎么办？后续可以人工处理
 */
@Component
@RequiredArgsConstructor
class RefreshCouponTaskDelayQueueRunner implements CommandLineRunner {

    private final CouponTaskMapper couponTaskMapper;
    private final RedissonClient redissonClient;

    @Override
    public void run(String... args) throws Exception {
        Executors.newSingleThreadExecutor(
                        runnable -> {
                            Thread thread = new Thread(runnable);
                            thread.setName("delay_coupon-task_send-num_consumer");
                            thread.setDaemon(Boolean.TRUE);
                            return thread;
                        })
                .execute(() -> {
                    RBlockingDeque<JSONObject> blockingDeque = redissonClient.getBlockingDeque("twocoupon-admin:delay-queue:COUPON_TASK_SEND_NUM_DELAY_QUEUE");
                    for (; ; ) {
                        try {
                            // 获取延迟队列已到达时间元素
                            JSONObject delayJsonObject = blockingDeque.take();
                            if (delayJsonObject != null) {
                                // 获取优惠券推送记录，查看发送条数是否已经有值，有的话代表上面线程池已经处理完成，无需再处理
                                CouponTaskDO couponTaskDO = couponTaskMapper.selectById(delayJsonObject.getLong("couponTaskId"));
                                if (couponTaskDO.getSendNum() == null) {
                                    refreshCouponTaskSendNum(delayJsonObject);
                                }
                            }
                        } catch (Throwable ignored) {
                        }
                    }
                });
    }

    private void refreshCouponTaskSendNum(JSONObject delayJsonObject) {
        // 通过 EasyExcel 监听器获取 Excel 中所有行数
        RowCountListener listener = new RowCountListener();
        EasyExcel.read(delayJsonObject.getString("fileAddress"), listener).sheet().doRead();
        int totalRows = listener.getRowCount();

        // 刷新优惠券推送记录中发送行数
        CouponTaskDO updateCouponTaskDO = CouponTaskDO.builder()
                .id(delayJsonObject.getLong("couponTaskId"))
                .sendNum(totalRows)
                .build();
        couponTaskMapper.updateById(updateCouponTaskDO);
    }
}